﻿//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace LS
{
    public static class BinaryReaderExtension
    {
        public static Color32 ReadColor32(this BinaryReader binaryReader)
        {
            return new Color32(binaryReader.ReadByte(), binaryReader.ReadByte(), binaryReader.ReadByte(), binaryReader.ReadByte());
        }

        public static Color ReadColor(this BinaryReader binaryReader)
        {
            return new Color(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
        }

        public static DateTime ReadDateTime(this BinaryReader binaryReader)
        {
            return new DateTime(binaryReader.ReadInt64());
        }

        public static Quaternion ReadQuaternion(this BinaryReader binaryReader)
        {
            return new Quaternion(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
        }

        public static Rect ReadRect(this BinaryReader binaryReader)
        {
            return new Rect(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
        }

        public static Vector2 ReadVector2(this BinaryReader binaryReader)
        {
            return new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
        }

        public static Vector3 ReadVector3(this BinaryReader binaryReader)
        {
            return new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
        }

        public static Vector4 ReadVector4(this BinaryReader binaryReader)
        {
            return new Vector4(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
        }

        public static bool[] ReadBoolArray(this BinaryReader binaryReader)
        {
            bool[] array = new bool[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadBoolean();
            }
            return array;
        }

        public static List<bool> ReadBoolList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<bool> array = new List<bool>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadBoolean());
            }
            return array;
        }

        public static Dictionary<string, bool> ReadBoolDictionary<T>(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, bool> dic = new Dictionary<string, bool>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadBoolean());
            }
            return dic;
        }

        public static byte[] ReadByteArray(this BinaryReader binaryReader)
        {
            byte[] array = new byte[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadByte();
            }
            return array;
        }

        public static List<byte> ReadByteList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<byte> array = new List<byte>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadByte());
            }
            return array;
        }

        public static Dictionary<string, byte> ReadByteDictionary<T>(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, byte> dic = new Dictionary<string, byte>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadByte());
            }
            return dic;
        }

        public static char[] ReadCharArray(this BinaryReader binaryReader)
        {
            char[] array = new char[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadChar();
            }
            return array;
        }

        public static List<char> ReadCharList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<char> array = new List<char>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadChar());
            }
            return array;
        }

        public static Dictionary<string, char> ReadCharDictionary<T>(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, char> dic = new Dictionary<string, char>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadChar());
            }
            return dic;
        }

        public static Color32[] ReadColor32Array(this BinaryReader binaryReader)
        {
            Color32[] array = new Color32[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadColor32();
            }
            return array;
        }

        public static List<Color32> ReadColor32List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Color32> array = new List<Color32>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadColor32());
            }
            return array;
        }

        public static Dictionary<string, Color32> ReadColor32Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Color32> dic = new Dictionary<string, Color32>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadColor32());
            }
            return dic;
        }

        public static Color[] ReadColorArray(this BinaryReader binaryReader)
        {
            Color[] array = new Color[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadColor();
            }
            return array;
        }

        public static List<Color> ReadColorList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Color> array = new List<Color>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadColor());
            }
            return array;
        }

        public static Dictionary<string, Color> ReadColorDictionary<T>(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Color> dic = new Dictionary<string, Color>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadColor());
            }
            return dic;
        }

        public static short[] ReadInt16Array(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            short[] array = new short[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadInt16();
            }
            return array;
        }

        public static List<short> ReadInt16List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<short> array = new List<short>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadInt16());
            }
            return array;
        }

        public static Dictionary<string, short> ReadInt16Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, short> dic = new Dictionary<string, short>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadInt16());
            }
            return dic;
        }

        public static int[] ReadInt32Array(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            int[] array = new int[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadInt32();
            }
            return array;
        }

        public static List<int> ReadInt32List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<int> array = new List<int>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadInt32());
            }
            return array;
        }

        public static Dictionary<string, int> ReadInt32Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, int> dic = new Dictionary<string, int>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadInt32());
            }
            return dic;
        }

        public static long[] ReadInt64Array(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            long[] array = new long[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadInt64();
            }
            return array;
        }

        public static List<long> ReadInt64List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<long> array = new List<long>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadInt64());
            }
            return array;
        }

        public static Dictionary<string, long> ReadInt64Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, long> dic = new Dictionary<string, long>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadInt64());
            }
            return dic;
        }

        public static float[] ReadSingleArray(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            float[] array = new float[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadSingle();
            }
            return array;
        }

        public static List<float> ReadSingleList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<float> array = new List<float>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadSingle());
            }
            return array;
        }

        public static Dictionary<string, float> ReadSingleDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, float> dic = new Dictionary<string, float>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadSingle());
            }
            return dic;
        }

        public static double[] ReadDoubleArray(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            double[] array = new double[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadDouble();
            }
            return array;
        }

        public static List<double> ReadDoubleList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<double> array = new List<double>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadDouble());
            }
            return array;
        }

        public static Dictionary<string, double> ReadDoubleDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, double> dic = new Dictionary<string, double>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadDouble());
            }
            return dic;
        }

        public static decimal[] ReadDecimalArray(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            decimal[] array = new decimal[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadDecimal();
            }
            return array;
        }

        public static List<decimal> ReadDecimalList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<decimal> array = new List<decimal>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadDecimal());
            }
            return array;
        }

        public static Dictionary<string, decimal> ReadDecimalDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, decimal> dic = new Dictionary<string, decimal>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadDecimal());
            }
            return dic;
        }

        public static ushort[] ReadUInt16Array(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            ushort[] array = new ushort[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadUInt16();
            }
            return array;
        }

        public static List<ushort> ReadUInt16List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<ushort> array = new List<ushort>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadUInt16());
            }
            return array;
        }

        public static Dictionary<string, ushort> ReadUInt16Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, ushort> dic = new Dictionary<string, ushort>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadUInt16());
            }
            return dic;
        }

        public static uint[] ReadUInt32Array(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            uint[] array = new uint[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadUInt32();
            }
            return array;
        }

        public static List<uint> ReadUInt32List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<uint> array = new List<uint>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadUInt32());
            }
            return array;
        }

        public static Dictionary<string, uint> ReadUInt32Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, uint> dic = new Dictionary<string, uint>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadUInt32());
            }
            return dic;
        }

        public static ulong[] ReadUInt64Array(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            ulong[] array = new ulong[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadUInt64();
            }
            return array;
        }

        public static List<ulong> ReadUInt64List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<ulong> array = new List<ulong>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadUInt64());
            }
            return array;
        }

        public static Dictionary<string, ulong> ReadUInt64Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, ulong> dic = new Dictionary<string, ulong>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadUInt64());
            }
            return dic;
        }

        public static string[] ReadStringArray(this BinaryReader binaryReader)
        {
            int length = binaryReader.ReadInt32();
            string[] array = new string[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = binaryReader.ReadString();
            }
            return array;
        }

        public static List<string> ReadStringList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<string> array = new List<string>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadString());
            }
            return array;
        }

        public static Dictionary<string, string> ReadStringDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, string> dic = new Dictionary<string, string>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadString());
            }
            return dic;
        }

        public static Quaternion[] ReadQuaternionArray(this BinaryReader binaryReader)
        {
            Quaternion[] array = new Quaternion[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadQuaternion();
            }
            return array;
        }

        public static List<Quaternion> ReadQuaternionList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Quaternion> array = new List<Quaternion>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadQuaternion());
            }
            return array;
        }

        public static Dictionary<string, Quaternion> ReadQuaternionDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Quaternion> dic = new Dictionary<string, Quaternion>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadQuaternion());
            }
            return dic;
        }

        public static Rect[] ReadRectArray(this BinaryReader binaryReader)
        {
            Rect[] array = new Rect[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadRect();
            }
            return array;
        }

        public static List<Rect> ReadRectList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Rect> array = new List<Rect>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadRect());
            }
            return array;
        }

        public static Dictionary<string, Rect> ReadRectDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Rect> dic = new Dictionary<string, Rect>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadRect());
            }
            return dic;
        }

        public static Vector2[] ReadVector2Array(this BinaryReader binaryReader)
        {
            Vector2[] array = new Vector2[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadVector2();
            }
            return array;
        }

        public static List<Vector2> ReadVector2List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Vector2> array = new List<Vector2>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadVector2());
            }
            return array;
        }

        public static Dictionary<string, Vector2> ReadVector2Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Vector2> dic = new Dictionary<string, Vector2>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadVector2());
            }
            return dic;
        }

        public static Vector3[] ReadVector3Array(this BinaryReader binaryReader)
        {
            Vector3[] array = new Vector3[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadVector3();
            }
            return array;
        }

        public static List<Vector3> ReadVector3List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Vector3> array = new List<Vector3>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadVector3());
            }
            return array;
        }

        public static Dictionary<string, Vector3> ReadVector3Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Vector3> dic = new Dictionary<string, Vector3>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadVector3());
            }
            return dic;
        }

        public static Vector4[] ReadVector4Array(this BinaryReader binaryReader)
        {
            Vector4[] array = new Vector4[binaryReader.ReadInt32()];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = binaryReader.ReadVector4();
            }
            return array;
        }

        public static List<Vector4> ReadVector4List(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<Vector4> array = new List<Vector4>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadVector4());
            }
            return array;
        }

        public static Dictionary<string, Vector4> ReadVector4Dictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, Vector4> dic = new Dictionary<string, Vector4>(count);
            for (int i = 0; i < count; i++)
            {
                dic.Add(binaryReader.ReadString(), binaryReader.ReadVector4());
            }
            return dic;
        }

        public static System.Numerics.BigInteger ReadBigInteger(this BinaryReader binaryReader)
        {
            byte[] ba = binaryReader.ReadByteArray();
            return new System.Numerics.BigInteger(ba);
        }

        public static System.Numerics.BigInteger[] ReadBigIntegerArray(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            System.Numerics.BigInteger[] array = new System.Numerics.BigInteger[count];
            for (int i = 0; i < count; i++)
            {
                array[i] = binaryReader.ReadBigInteger();
            }
            return array;
        }

        public static List<System.Numerics.BigInteger> ReadBigIntegerList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<System.Numerics.BigInteger> array = new List<System.Numerics.BigInteger>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadBigInteger());
            }
            return array;
        }

        public static Dictionary<string, System.Numerics.BigInteger> ReadBigIntegerDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, System.Numerics.BigInteger> collector = new Dictionary<string, System.Numerics.BigInteger>();
            for (int i = 0; i < count; i++)
            {
                collector.Add(binaryReader.ReadString(), binaryReader.ReadBigInteger());
            }
            return collector;
        }
#if BIG_DECIMAL
        public static ExtendedNumerics.BigDecimal ReadBigDecimal(this BinaryReader binaryReader)
        {
            int exponent = binaryReader.ReadInt32();
            var bi = new System.Numerics.BigInteger(binaryReader.ReadByteArray());
            return new ExtendedNumerics.BigDecimal(bi,exponent);
        }

        public static ExtendedNumerics.BigDecimal[] ReadBigDecimalArray(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            ExtendedNumerics.BigDecimal[] array = new ExtendedNumerics.BigDecimal[count];
            for (int i = 0; i < count; i++)
            {
                array[i] = binaryReader.ReadBigDecimal();
            }
            return array;
        }

        public static List<ExtendedNumerics.BigDecimal> ReadBigDecimalList(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            List<ExtendedNumerics.BigDecimal> array = new List<ExtendedNumerics.BigDecimal>(count);
            for (int i = 0; i < count; i++)
            {
                array.Add(binaryReader.ReadBigDecimal());
            }
            return array;
        }

        public static Dictionary<string, ExtendedNumerics.BigDecimal> ReadBigDecimalDictionary(this BinaryReader binaryReader)
        {
            int count = binaryReader.ReadInt32();
            Dictionary<string, ExtendedNumerics.BigDecimal> collector = new Dictionary<string, ExtendedNumerics.BigDecimal>();
            for (int i = 0; i < count; i++)
            {
                collector.Add(binaryReader.ReadString(), binaryReader.ReadBigDecimal());
            }
            return collector;
        }
#endif
    }
}
